package agu.misc;

import java.io.*;

public class IoUtil extends ByteArrayOutputStream
{
    Object input;
    boolean bytesReady;

    public static IoUtil withInput(InputStream input){
        return new IoUtil(input);
    }

    public static IoUtil withInput(File input){
        return new IoUtil(input);
    }

    public static IoUtil withInput(String input){
        return new IoUtil(input);
    }

    private IoUtil(Object input){
        this.input = input;
    }

    public IoUtil output(OutputStream output){
        io(output);
        return this;
    }

    public IoUtil output(File output){
        io(output);
        return this;
    }

    public IoUtil output(String output){
        io(output);
        return this;
    }

    synchronized OutputStream io(Object output){
        InputStream inputStream = null;
        try{
            if(input instanceof InputStream){
                inputStream = (InputStream)input;
            }else if(input instanceof File){
                inputStream = new FileInputStream((File)input);
            }else if(input != null){
                inputStream = new FileInputStream(input.toString());
            }
        }catch(Exception ex){
            ex.printStackTrace();
        }
        if(inputStream == null) return null;

        OutputStream outputStream = null;
        try{
            if(output instanceof OutputStream){
                outputStream = (OutputStream)output;
            }else if(output instanceof File){
                outputStream = new FileOutputStream((File)output);
            }else if(output != null){
                outputStream = new FileOutputStream(output.toString());
            }else{
                outputStream = new ByteArrayOutputStream();
            }

            byte[] buffer = new byte[10 * 1024];
            while(true){
                int read = inputStream.read(buffer, 0, buffer.length);
                if(read == -1) break;
                if(read == 0) continue;
                outputStream.write(buffer, 0, read);
            }
        }catch(Exception ex){
            ex.printStackTrace();
        }

        close(inputStream);

        close(outputStream);

        return outputStream;
    }

    public static void close(Closeable stream){
        if(stream != null){
            try{
                stream.close();
            }catch(Exception ex){
                ex.getClass();
            }
        }
    }

    public synchronized byte[] toByteArray(){
        if(!bytesReady){
            OutputStream outputStream = io(this);
            if(outputStream != null) bytesReady = true;
        }
        return super.toByteArray();
    }

    public String toString(String charsetName){
        try{
            return new String(toByteArray(), charsetName);
        }catch(Exception ex){
            return "";
        }
    }

    public String toString(){
        return toString("utf-8");
    }
}
